<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import * as echarts from 'echarts'
import type { ECharts } from 'echarts'
import 'echarts-liquidfill'
import { chunk, uniq } from 'lodash'
// import {Autoplay} from "swiper";
import { Swiper, SwiperSlide } from 'swiper/vue/swiper-vue'
import { windowResize, xAxis, yAxis, series, tooltip } from '@/views/common'
import {
  xmBarRequest,
  xmLineRequest,
  xmPieRequest,
  xmTopRequest,
} from '@/views/cockpit/projectSection/api'
import { isSuccess } from '@/views/cockpit/common'
import moment from 'moment/moment'
import { getDictionary } from '@/views/science/api/technologyawards'
import { fontSizeRem } from '@/utils/utils'

enum loopKey {
  projectName = 'project_name',
  money = 'total_funding',
  status = 'status',
  time = 'end_time',
}
type LoopData = {
  [key in Exclude<loopKey, loopKey.money>]: string
} & {
  [loopKey.money]: number
}

const yearValue = ref<string>(moment().format('YYYY'))
const level = ref<string>('')
const levelOptions = ref<Record<string, string>[]>([])
const ball = ref<HTMLDivElement>()
const line = ref<HTMLDivElement>()
const step = ref<HTMLDivElement>()
let ballChart: ECharts
let lineChart: ECharts
let stepChart: ECharts

// 渲染图表
const initChart = async () => {
  const levelData = await getDictionary(['XMZX_LEVEL_TYPE'])
  if (isSuccess(levelData)) levelOptions.value = levelData.data.data.XMZX_LEVEL_TYPE || []
  initBallChart()
  initLineChat()
  initBarChat()
}

const renderData = ref<number>(0)
const initBallChart = async () => {
  const res = await xmPieRequest(yearValue.value, level.value)
  const data = res.data?.data || []
  const num1 = data[0]?.num1 || 0
  const num2 = data[1]?.num2 || 0
  renderData.value = num2 === 0 ? 0 : +(num1 / num2).toFixed(2)
  if (ballChart) ballChart.dispose()
  ballChart = echarts.init(ball.value)
  ballChart.setOption({
    series: [
      {
        type: 'liquidFill',
        data: [renderData.value],
        center: ['50%', '50%'],
        radius: '76%',
        label: {
          show: false,
        },
        color: ['#49A5B6'],
        backgroundStyle: {
          borderWidth: 2,
          borderColor: '#49A5B6',
          color: 'transparent',
        },
        outline: {
          itemStyle: {
            borderWidth: 2,
            borderColor: '#49A5B6',
            opacity: 0.15,
          },
        },
      },
    ],
  })
}

const totalNum = ref<number>(0)
const initLineChat = () => {
  xmLineRequest(yearValue.value).then((res) => {
    if (isSuccess(res)) {
      const data = res.data.data || []
      const lineX = data.map((t) => t.level) || []
      const lineY = data.map((t) => t.num) || []
      totalNum.value = lineY.reduce((now: number, next: number) => now + next, 0)
      if (lineChart) lineChart.dispose()
      lineChart = echarts.init(line.value)
      lineChart.setOption({
        tooltip,
        grid: {
          top: '15',
          left: '0',
          right: '2',
          bottom: '0',
          containLabel: true,
        },
        xAxis: {
          ...xAxis(lineX, false),
        },
        yAxis: yAxis(false),
        series: [
          {
            data: lineY,
            type: 'line',
            roam: false,
            symbolSize: 8,
            smooth: true,
            barWidth: fontSizeRem(0.3),
            itemStyle: {
              // color: '#C7A746',
              color: function (params) {
                //展示正值的柱子，负数设为透明
                let colorArr = params.value > 0 ? ['#5470C6', '#08103B'] : ['#08103B', '#5470C6']
                return new echarts.graphic.LinearGradient(
                  0,
                  0,
                  0,
                  1,
                  [
                    {
                      offset: 0,
                      color: colorArr[0], // 0% 处的颜色
                    },
                    {
                      offset: 1,
                      color: colorArr[1], // 100% 处的颜色
                    },
                  ],
                  false
                )
              },
              barBorderRadius: [30, 30, 0, 0],
            },
          },
        ],
      })
    } else if (lineChart) lineChart.dispose()
  })
}
const initBarChat = () => {
  xmBarRequest(yearValue.value).then((res) => {
    if (isSuccess(res)) {
      const data = res.data.data || []
      const lineX: string[] = uniq(data.map((t) => t.level)) || []
      const lineY1 = data.filter((t) => t.type === '在研项目').map((t) => t.num) || []
      const lineY2 = data.filter((t) => t.type === '延期项目').map((t) => t.num) || []
      const lineY3 = data.filter((t) => t.type === '结题项目').map((t) => t.num) || []
      const lineY4 = data.filter((t) => t.type === '中止项目').map((t) => t.num) || []
      if (stepChart) stepChart.dispose()
      stepChart = echarts.init(step.value)
      stepChart.setOption({
        tooltip,
        grid: {
          top: '50',
          left: '10',
          right: '2',
          bottom: '0',
          containLabel: true,
        },
        legend: {
          itemWidth: 14,
          textStyle: {
            color: '#fff',
          },
          left: '18%',
          top: 0,
        },
        xAxis: {
          axisPointer: {
            type: 'shadow',
          },
          ...xAxis(lineX, false, lineX.length),
        },
        yAxis: yAxis(false),
        color:['#0272FC','#C2AC50','#6629D0','#49A5B6'],
        series: [
          {
            ...series(lineY1, '#0272FC', '在研'),
            barWidth: fontSizeRem(0.3),
            itemStyle: {
              // color: '#C7A746',
              color: function (params) {
                //展示正值的柱子，负数设为透明
                let colorArr = params.value > 0 ? ['#0272FC', '#08103B'] : ['#08103B', '#0272FC']
                return new echarts.graphic.LinearGradient(
                  0,
                  0,
                  0,
                  1,
                  [
                    {
                      offset: 0,
                      color: colorArr[0], // 0% 处的颜色
                    },
                    {
                      offset: 1,
                      color: colorArr[1], // 100% 处的颜色
                    },
                  ],
                  false
                )
              },
              barBorderRadius: [30, 30, 0, 0],
            },
            label: {
              show: true,
              position:'top',
            },
          },
          {
            ...series(lineY2, '#C2AC50', '延期'),
            barWidth: fontSizeRem(0.3),
            itemStyle: {
              // color: '#C7A746',
              color: function (params) {
                //展示正值的柱子，负数设为透明
                let colorArr = params.value > 0 ? ['#C2AC50', '#08103B'] : ['#08103B', '#C2AC50']
                return new echarts.graphic.LinearGradient(
                  0,
                  0,
                  0,
                  1,
                  [
                    {
                      offset: 0,
                      color: colorArr[0], // 0% 处的颜色
                    },
                    {
                      offset: 1,
                      color: colorArr[1], // 100% 处的颜色
                    },
                  ],
                  false
                )
              },
              barBorderRadius: [30, 30, 0, 0],
            },
            label: {
              show: true,
              position:'top',
            },
          },
          {
            ...series(lineY3, '#6629D0', '已完成'),
            barWidth: fontSizeRem(0.3),
            itemStyle: {
              // color: '#C7A746',
              color: function (params) {
                //展示正值的柱子，负数设为透明
                let colorArr = params.value > 0 ? ['#6629D0', '#08103B'] : ['#08103B', '#6629D0']
                return new echarts.graphic.LinearGradient(
                  0,
                  0,
                  0,
                  1,
                  [
                    {
                      offset: 0,
                      color: colorArr[0], // 0% 处的颜色
                    },
                    {
                      offset: 1,
                      color: colorArr[1], // 100% 处的颜色
                    },
                  ],
                  false
                )
              },
              barBorderRadius: [30, 30, 0, 0],
            },
            label: {
              show: true,
              position:'top',
            },
          },
          {
            ...series(lineY4, '#49A5B6', '中止'),
            barWidth: fontSizeRem(0.3),
            itemStyle: {
              // color: '#C7A746',
              color: function (params) {
                //展示正值的柱子，负数设为透明
                let colorArr = params.value > 0 ? ['#49A5B6', '#08103B'] : ['#08103B', '#49A5B6']
                return new echarts.graphic.LinearGradient(
                  0,
                  0,
                  0,
                  1,
                  [
                    {
                      offset: 0,
                      color: colorArr[0], // 0% 处的颜色
                    },
                    {
                      offset: 1,
                      color: colorArr[1], // 100% 处的颜色
                    },
                  ],
                  false
                )
              },
              barBorderRadius: [30, 30, 0, 0],
            },
            label: {
              show: true,
              position:'top',
            },
          },
        ],
      })
    }
  })
}

const windowEvent = () => {
  windowResize(300, () => {
    if (ballChart) ballChart.resize()
    if (lineChart) lineChart.resize()
    if (stepChart) stepChart.resize()
  })
}

const lineHeight: number = 50
const loopYear = ref<string>(moment().format('YYYY'))
const loopResult = ref<LoopData[][]>([])
const getLoopData = () => {
  loopResult.value = []
  xmTopRequest(loopYear.value).then((res) => {
    if (isSuccess(res)) {
      const data = (res.data.data || []) as LoopData[]
      const el: Element = document.getElementsByClassName('swiperContent')[0]
      let height: number = 0
      let chunkNum: number = 0
      if (el) {
        height = el.clientHeight
        chunkNum = Math.floor(height / lineHeight)
      }
      loopResult.value = chunk(data, chunkNum)
    }
  })
}
onMounted(() => {
  initChart()
  initLineChat()
  initBarChat()
  getLoopData()
  window.addEventListener('resize', () => {
    windowEvent()
  })
})
onUnmounted(() => {
  window.removeEventListener('resize', windowEvent)
})
</script>

<template>
  <div class="chartContent">
    <div class="project">
      <div class="search">
        <div class="mr20">
          <el-date-picker
            v-model="yearValue"
            type="year"
            placeholder="选择年度"
            value-format="YYYY"
            format="YYYY"
            clearable
            @change="initChart"
          />
        </div>
        <el-select v-model="level" placeholder="项目等级" clearable @change="initBallChart">
          <el-option
            v-for="item in levelOptions"
            :key="item.itemValue"
            :label="item.itemText"
            :value="item.itemValue"
          />
        </el-select>
      </div>
      <div class="searchContent">
        <div class="view">
          <div class="ball">
            <div class="label">
              <span class="description">项目进度</span>
              <span class="description description_num">{{ (renderData * 100).toFixed(2) }}%</span>
              <span class="description description_small">验收成功</span>
            </div>
            <div ref="ball" class="chat"></div>
          </div>
          <div class="line">
            <div class="title">
              <span class="unit">项目总览(共{{ totalNum }}个)</span>
              <!-- <span>项目总览(共{{ totalNum }}个)</span> -->
            </div>
            <div ref="line" class="chat"></div>
          </div>
        </div>
        <div class="step">
          <div class="description">
            项目进度一览图
          </div>
          <div ref="step" class="chat"></div>
        </div>
      </div>
    </div>
    <div class="ranking">
      <div class="title">项目TOP50</div>
      <div class="searchItem searchRight">
        <el-date-picker
          v-model="loopYear"
          type="year"
          placeholder="选择年度"
          value-format="YYYY"
          format="YYYY"
          clearable
          @change="getLoopData"
        />
      </div>
      <div class="rankContent">
        <div class="rankLi head">
          <div class="item">
            <div class="td"><span class="txt">截止时间</span></div>
            <div class="td"><span class="txt">项目名称</span></div>
            <div class="td"><span class="txt">金额 (万)</span></div>
            <div class="td"><span class="txt">状态</span></div>
          </div>
        </div>
        <!--:modules="[Autoplay]"
                :autoplay="{delay: 6000, disableOnInteraction: false}"
                loop observer observe-parents-->
        <swiper class="swiperContent" direction="vertical">
          <swiper-slide v-for="(slide, index) in loopResult" :key="index + 'slide'">
            <div class="rankLi body">
              <div class="item item_list" v-for="(option, idx) in slide" :key="index + 'slide' + idx">
                <div class="td">
                  <span class="txt">{{ option.end_time }}</span>
                </div>
                <div class="td" :title="option.project_name || ''">
                  <span class="txt">{{ option.project_name }}</span>
                </div>
                <div class="td">
                  <span class="txt">{{ option.total_funding }}</span>
                </div>
                <div class="td">
                  <span :class="option.status=='紧急'?'txt_yellow':(option.status=='逾期'?'txt_red':'txt_green')" >{{ option.status }}</span>
                </div>
              </div>
            </div>
          </swiper-slide>
        </swiper>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
@import '@/assets/css/theme.scss';
@import '../../common';
.title {
  position: relative;
  font-size: 14px;
  color: #fff;
  text-align: center;
  margin-bottom: 2rem;
  .unit {
    font-size: 18px;
    position: absolute;
    left: 0;
    top: 0;
  }
}
.chartContent {
  .project {
    display: flex;
    flex-direction: column;
    flex: 1 1 0;
    padding: 3vh 1.5vh;
    background-image: url(../../img/project-bg.png);
    background-size: 100% 100%;
    // border: 1px solid $primary-color;
    .search {
      display: flex;
      margin-bottom: 10px;
    }
    .searchContent {
      display: flex;
      flex-direction: column;
      flex: 1 1 0;
      .view {
        display: flex;
        // background-color: #432828;
        padding: 3%;
        height: calc(3 / 7 * 100%);
        .ball {
          position: relative;
          display: flex;
          width: 30%;
          margin-right: 5%;
          height: 100%;
          .label {
            position: absolute;
            top: 50%;
            left: 50%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-content: center;
            align-self: center;
            transform: translate(-50%, -50%);
            z-index: 1;
            font-size: 20px;
            color: #fff;
            text-align: center;
            .description {
              line-height: 20px;
              margin-bottom: 10px;
              &:last-child {
                margin-bottom: 0;
              }
            }
            .description_num{
              margin-top: .5rem;
            }
            .description_small{
              font-size: 14px;
            }
          }
        }
        .line {
          display: flex;
          flex-direction: column;
          // width: 70%;
          flex: 1;
          height: 100%;
        }
      }
      .step {
        position: relative;
        display: flex;
        padding-top: 20px;
        margin-top: 2vh;
        height: calc(4 / 7 * 100%);
        box-sizing: border-box;
        .description {
          position: absolute;
          top: 10px;
          left: 0;
          display: flex;
          font-size: 18px;
          align-items: center;
          color: #fff;
          margin-bottom: 30px;
        }
      }
    }
  }
  .ranking {
    background-image: url(../../img/ranking-bg.png);
    background-size: 100% 100%;
  }
}
</style>
